#include "Voleur.h"
#include <iostream>
//#include "lib.h"
using namespace std;

/*
  Changer tous les ajustements au compétences .... :@
  dus à la race et à la dext. :'(
*/

unsigned int Voleur::comp_base[21] = {
  100, 5, 10, 10, 15, 5, 10, 100, 10, 60, 100, 0, 15, 5, 100, 100, 5, 15, 100,
  100, 100
};

const unsigned int Voleur::nbr_comp = 21;

const unsigned int Voleur::nbr_restric = 0;

ListComp Voleur::Comp[21] = {
  {"Attaque sournoise"                 , 10, false},
  {"Corruption"                        , 5 , true}, // base = 5%
  {"Crochetage"                        , 10, true}, // base = 10%
  {"Déplacement silencieux"            , 5 , true}, // base = 10%
  {"Détection des bruits"              , 5 , true}, // base = 15%
  {"Détection de la magie"             , 10, true}, // base = 5%
  {"Détection des illusions"           , 10, true}, // base = 10%
  {"Esquive"                           , 10, false},
  {"Evasion"                           , 10, true}, // base = 10%
  {"Grimper"                           , 5 , true}, // base = 60%
  {"Jargon des voleurs"                , 5 , false},
  {"Lire des langues inconnues"        , 5 , true}, // base = 0%
  {"Percer un tunnel"                  , 10, true}, // base = 15%
  {"Se cacher dans l'ombre"            , 5 , true}, // base = 5%
  {"Suivant (niveau 10)"               , 5 , false},
  {"Suivants"                          , 10, false},
  {"Trouver et désamorcer les pièges"  , 10, true}, // base = 5%
  {"Vol à la tire"                     , 10, true}, // base = 15%
  {"Utilisation de parchemins (niv 10)", 5 , false},
  {"Utilisation de parchemins"         , 10, false},
  {"Specialisation"                    , 15, false}   
};

Voleur::Voleur(unsigned int xp, unsigned int trait[7], unsigned int& PP)
  : Classe(xp, trait, Roublards)
{
  Type_classe = "Voleur";
  PP += 80;
  dout(BLANK) << setfill('*') << setw(56) << '*' << endl;
  dout(BLANK) << "Création d'un voleur" << endl << endl;
  unsigned int nbr(0);

  dout(BLANK) << "Tu as " << PP << " pp à dépenser" << endl;

  for (unsigned int i(0); i<nbr_comp; i++)
    dout(BLANK) << i+1 << ' ' << Comp[i].Comp << " (" << Comp[i].Cout
		<< " pp)" << endl;	
  dout(BLANK) << nbr_comp+1 << " Aucune" << endl;
  dout(BLANK) << "Choisir les compétences de classe" << endl;

  bool test(true), deja_pris, encore(false);
  unsigned int save_PP(PP);

  do
    {
      do
	{
	  nbr = demander_unsigned_borne("("+write_int(PP)+" restants) ", 1,
					nbr_comp + 1);
	  if (nbr!=nbr_comp+1)
	    {
	      if (PP >= Comp[nbr-1].Cout)
		{
		  deja_pris = safe_push_back(&Comp_classe, nbr - 1);
		  if (deja_pris)
		    dout(WARN) << "Déjà sélectrionné" << endl;
		  else
		    {
		      Comp_classe.push_back(nbr-1);
		      PP -= Comp[nbr-1].Cout;
		      dout(BLANK) << "Compétence choisie : " << Comp[nbr-1].Comp 
				  << endl;
		      if (Comp[nbr-1].Pourcentage)
			{
			  Comp_classe.push_back(comp_base[nbr-1]);
			  dout(DEBUG) << nbr-1 << " => " << Comp[nbr-1].Comp
				      << " " << comp_base[nbr-1] << endl;
			}
		      else
			dout(DEBUG) << nbr-1 << " => " << Comp[nbr-1].Comp << endl;
		    }
		}
	      else
		dout(BLANK) << "Pas assez de pp" << endl;
	    }
	  else
	    test = false;
	}
      while(test);

      affiche_competences();
      dout(BLANK) << endl <<  "1 pour continuer, 2 pour recommencer" << endl;
      nbr = demander_unsigned_borne("Choix ", 1, 2);
      if (nbr == 2)
	{
	  PP = save_PP;
	  Comp_classe.clear();
	  test = true;
	  encore = true;
	  dout(BLANK) << endl;
	}
      else
	encore = false;
    }
  while(encore);

  dout(BLANK) << endl << setfill('*') << setw(56) << '*' << endl;
  calcul_niveau();
  augmenter_talents(30, false);
}

Voleur::Voleur(unsigned int xp, unsigned int trait[7])
  : Classe(xp, trait, Roublards)
{
  Type_classe = "Voleur";
  calcul_niveau();
}

Voleur::~Voleur()
{}

void Voleur::calcul_niveau()
{
  if (XP < 75000)
    {
      unsigned int i;
      for (i = 0; i < 5; i++)
	{
	  if (XP < (unsigned int) 1250 * puissance(2, i))
	    break;
	}
      Niveau = i + 1;
    }
  else if (XP < 70000)
    Niveau = 7;
  else if (XP < 110000)
    Niveau = 8;
  else if (XP < 160000)
    Niveau = 9;
  else if (XP < 220000)
    Niveau = 10;
  else
      Niveau = (XP - 220000) / 220000 + 11;
}

void Voleur::afficher_stats()
{
  dout(BLANK) << "Voleur" << endl;
  for (unsigned int i(0); i<6; i++)
    dout(BLANK) << Caracteristiques[i] << ' ' << Traits[i] << endl;
  for (unsigned int i(0); i<Comp_classe.size(); i++)
    {
      if(Comp[Comp_classe[i]].Pourcentage)
	{
	  dout(BLANK) << Comp[Comp_classe[i]].Comp << ' ' << Comp_classe[i+1];
	  dout(BLANK) << '%' << endl;
	  i++;
	}
      else
	dout(BLANK) << Comp[Comp_classe[i]].Comp << endl;
    }
}

void Voleur::appliquer_modif(const string& type)
{
  if (type == "Nain")
    {
      comp_base[2]  += 10;  // crochetage
      comp_base[16] += 15;  // détection des pièges
      comp_base[9]  -= 10;  // escalade
      comp_base[11] -= 5;   // lire des langues inconnues
      comp_base[5]  += 5;   // détection de la magie
      comp_base[6]  += 5;   // détection des illusions
      comp_base[1]  -= 5;   // corruption
      comp_base[12] += 10;  // creuser des tunnels
    }
  else if (type == "Elfe")
    {
      comp_base[16] += 5;   // vol à la tire
      comp_base[2]  -= 5;   // crochetage
      comp_base[3]  += 5;   // mouvement silencieux
      comp_base[13] += 10;  // se cacher dans l'ombre
      comp_base[4]  += 5;   // détection des bruits
      comp_base[5]  += 10;  // détection de la magie
      comp_base[1]  += 15;  // corruption
      comp_base[12] -= 10;  // creuser des tunnels
    }
  else if (type == "Gnome")
    {
      comp_base[2]  += 5;   // crochetage
      comp_base[16] += 10;  // détection des pièges
      comp_base[3]  += 5;   // mouvement silencieux
      comp_base[13] += 5;   // se cacher dans l'ombre
      comp_base[4]  += 10;  // détection des bruits
      comp_base[9]  -= 15;  // escalade
      comp_base[5]  += 5;   // détection de la magie
      comp_base[6]  += 10;  // détection des illusions
      comp_base[1]  += 5;   // corruption
      comp_base[12] += 5;   // creuser des tunnels
    }
  else if (type == "Demi-Elfe")
    {
      comp_base[16] += 10;  // vol à la tire
      comp_base[13] += 5;   // se cacher dans l'ombre
      comp_base[5]  += 5;   // détection de la magie
      comp_base[6]  += 5;   // détection des illusions
      comp_base[1]  += 5;   // corruption
      comp_base[12] -= 5;   // creuser des tunnels
    }
  else if (type == "Demi-Orque")
    {
      comp_base[16] += 5;   // détection des pièges
      comp_base[4]  += 5;   // détection des bruits
      comp_base[6]  -= 5;   // détection des illusions
      comp_base[1]  += 10;  // corruption
    }
  else if (type == "Hobbit")
    {
      comp_base[16] += 5;   // vol à la tire
      comp_base[2]  += 5;   // crochetage
      comp_base[16] += 5;   // détection des pièges
      comp_base[3]  += 10;  // mouvement silencieux
      comp_base[13] += 15;  // se cacher dans l'ombre
      comp_base[4]  += 10;  // détection des bruits
      comp_base[9]  -= 15;  // escalade
      comp_base[11] -= 5;   // lire des langues inconnues
      comp_base[5]  += 5;   // détection de la magie
      comp_base[12] += 5;   // creuser des tunnels
      comp_base[8]  += 10;  // évasion
    }

  switch(Traits[1])
    {
    case 9:
      comp_base[16] -= 15;  // vol à la tire
      comp_base[2]  -= 10;  // crochetage
      comp_base[16] -= 10;  // détection des pièges
      comp_base[3]  -= 20;  // mouvement silencieux
      comp_base[13] -= 10;  // se cacher dans l'ombre
      comp_base[9]  -= 10;  // escalade
      comp_base[12] -= 10;  // creuser des tunnels
      comp_base[8]  -= 15;  // évasion
      break;
    case 10:
      comp_base[16] -= 10;  // vol à la tire
      comp_base[2]  -= 5;   // crochetage
      comp_base[16] -= 10;  // détection des pièges
      comp_base[3]  -= 15;  // mouvement silencieux
      comp_base[13] -= 5;   // se cacher dans l'ombre
      comp_base[9]  -= 5;   // escalade
      comp_base[12] -= 5;   // creuser des tunnels
      comp_base[8]  -= 10;  // évasion
      break;
    case 11:
      comp_base[16] -= 5;   // vol à la tire
      comp_base[16] -= 5;   // détection des pièges
      comp_base[3]  -= 10;  // mouvement silencieux
      comp_base[8]  -= 5;   // évasion
      break;
    case 12:
      comp_base[3]  -= 5;   // mouvement silencieux
      break;
    case 16:
      comp_base[2]  += 5;   // crochetage
      break;
    case 17:
      comp_base[16] += 5;   // vol à la tire
      comp_base[2]  += 10;  // crochetage
      comp_base[3]  += 5;   // mouvement silencieux
      comp_base[13] += 5;   // se cacher dans l'ombre
      comp_base[9]  += 5;   // escalade
      comp_base[8]  += 5;   // évasion
      break;
    case 18:
      comp_base[16] += 10;  // vol à la tire
      comp_base[2]  += 15;  // crochetage
      comp_base[16] += 5;   // détection des pièges
      comp_base[3]  += 10;  // mouvement silencieux
      comp_base[13] += 10;  // se cacher dans l'ombre
      comp_base[9]  += 10;  // escalade
      comp_base[12] += 5;   // creuser des tunnels
      comp_base[8]  += 10;  // évasion
      break;
    case 19:
      comp_base[16] += 15;  // vol à la tire
      comp_base[2]  += 20;  // crochetage
      comp_base[16] += 10;  // détection des pièges
      comp_base[3]  += 15;  // mouvement silencieux
      comp_base[13] += 15;  // se cacher dans l'ombre
      comp_base[9]  += 15;  // escalade
      comp_base[12] += 10;  // creuser des tunnels
      comp_base[8]  += 15;  // évasion
      break;
    case 20:
      comp_base[16] += 20;  // vol à la tire
      comp_base[2]  += 20;  // crochetage
      comp_base[16] += 15;  // détection des pièges
      comp_base[3]  += 15;  // mouvement silencieux
      comp_base[13] += 20;  // se cacher dans l'ombre
      comp_base[9]  += 20;  // escalade
      comp_base[12] += 15;  // creuser des tunnels
      comp_base[8]  += 20;  // évasion
      break;
    case 21:
      comp_base[16] += 20;  // vol à la tire
      comp_base[2]  += 25;  // crochetage
      comp_base[16] += 20;  // détection des pièges
      comp_base[3]  += 20;  // mouvement silencieux
      comp_base[13] += 25;  // se cacher dans l'ombre
      comp_base[9]  += 20;  // escalade
      comp_base[12] += 20;  // creuser des tunnels
      comp_base[8]  += 25;  // évasion
      break;
    case 22:
      comp_base[16] += 25;  // vol à la tire
      comp_base[2]  += 25;  // crochetage
      comp_base[16] += 20;  // détection des pièges
      comp_base[3]  += 20;  // mouvement silencieux
      comp_base[13] += 30;  // se cacher dans l'ombre
      comp_base[9]  += 25;  // escalade
      comp_base[12] += 30;  // creuser des tunnels
      comp_base[8]  += 30;  // évasion
      break;
    }

  unsigned int combien_comp(Comp_classe.size()), valeur;
  vector<unsigned int> tmp;
  for (unsigned int i(0); i< combien_comp; i++)
    {
      valeur = Comp_classe[i];
      if (Comp[valeur].Pourcentage)
	{
	  tmp.push_back(valeur);
	  tmp.push_back(comp_base[valeur]);
	  i++;
	}
      else
       tmp.push_back(valeur);
    }
  Comp_classe.clear();
  for (unsigned int i(0); i< combien_comp; i++)
    {
      if (tmp[i] > 100)	
	Comp_classe.push_back(0);
      else
	Comp_classe.push_back(tmp[i]);
    }
}

void Voleur::augmenter_talents(const unsigned int& bonus,
			       const bool& lvl_up)
{
  vector<unsigned int> quelle, combien;
  unsigned int taille(get_combien()), nbr(0), depense, laquelle;

  for (unsigned int i(0); i<taille; i++)
    {
      dout(DEBUG) << Comp_classe[i];
      if (Comp[Comp_classe[i]].Pourcentage)
	{
	  dout(DEBUG) << " -> oui";
	  quelle.push_back(Comp_classe[i]);
	  combien.push_back(Comp_classe[i+1]);
	  i++;
	  nbr++;
	}
      dout(DEBUG) << endl;
    }

  unsigned int pps(bonus);
  dout(BLANK) << "Tu as " << pps << " point à dépenser dans les compétences";
  dout(BLANK) <<" suivantes:" << endl;
  for (unsigned int i(0); i<nbr; i++)
    {
      dout(DEBUG) << quelle[i] << " => " << Comp[quelle[i]].Comp << endl;
      dout(BLANK) << i+1 << " " << Comp[quelle[i]].Comp << " " << combien[i] 
		  << "%" << endl;
    }

  string poubelle;

  do
    {
      laquelle =
	demander_unsigned_borne("Quelle compétence veux-tu améliorer? ", 1,
				nbr + 1);

      depense = demander_unsigned_borne("De combien? ", 0, pps);

      combien[laquelle-1] += depense;
      pps -= depense;
    }
  while(pps!=0);

  vector<unsigned int> tmp;
  unsigned int j(0);

  for (unsigned int i(0); i<taille; i++)
    {
      if (Comp[Comp_classe[i]].Pourcentage)
	{
	  tmp.push_back(Comp_classe[i]);
	  tmp.push_back(combien[j]);
	  j++;
	  i++;
	}
      else
	tmp.push_back(Comp_classe[i]);
    }
  Comp_classe.clear();
   for (unsigned int i(0); i<taille; i++)
     Comp_classe.push_back(tmp[i]);
  
}

void Voleur::get_JS(unsigned int *tab) const
{
  *(tab + 0) = 13; // Paralysie, Poison ou Mort magique
  *(tab + 1) = 14; // Bâton, batonnet baguette
  *(tab + 2) = 12; // Pétrification ou Métamorphose
  *(tab + 3) = 16; // Souffles
  *(tab + 4) = 15; // Sorts
  
  unsigned int cat;
  if (Niveau <= 4)
    cat = 0;
  else  if (Niveau <= 8)
    cat = 1;
  else  if (Niveau <= 12)
    cat = 2;
  else  if (Niveau <= 16)
    cat = 3;
  else  if (Niveau <= 20)
    cat = 4;
  else
    cat = 5;

  *(tab + 0) -= cat;
  *(tab + 1) -= 2 * cat;
  *(tab + 2) -= cat;
  *(tab + 3) -= cat;
  *(tab + 4) -= 2 * cat;
}

string Voleur::get_competence(const unsigned int& i) const
{
  if (Comp[get_comp(i)].Pourcentage)
    return " " + Comp[get_comp(i)].Comp + " " + write_int(get_comp(i+1))
      + "\\%";
  else
    return Comp[get_comp(i)].Comp;
}

unsigned int Voleur::calcule_TAc0() const
{
  unsigned int mod_niveau((Niveau - 1) / 2);

  return 20 - mod_niveau;
}

void Voleur::calcul_niv_mag()
{
  Niveau_mag = 0;
}

void Voleur::ecrire_sorts(const string& nom_fichier, const bool& ecrase) const
{
  DebugLevelType etat_precedent(dout.getLevel());
  dout.setLevel(fonction);
  dout(DEBUG) << "Rien à faire" << endl << flush;
  ofstream sortie;
  if (ecrase)
    sortie.open(nom_fichier.c_str());
  else
    sortie.open(nom_fichier.c_str(), ios::app);
  sortie << "%"  << get_classe() << endl << "% rien à dire" << endl;
  sortie.close();
  dout.setLevel(etat_precedent);
}

void Voleur::nbr_sort(unsigned int sorts[], const unsigned int& taille) const
{
  DebugLevelType etat_precedent(dout.getLevel());
  dout.setLevel(fonction);
  dout(DEBUG) << "Rien à faire, mais proprement" << endl;
  dout.setLevel(etat_precedent);
}
